/*
 * File:    ServiceContext.java
 * Created: 07-Apr-2006
 * Version: $Id: //depot/bitgate/bsse/src/bitgate/util/service/ServiceContext.java#1 $
 *
 * COPYRIGHT (C) 2006, Bitgate Software, LLC.  All Rights Reserved.
 *
 * software@bitgatesoftware.com
 */

package com.bitgate.util.service;

import static com.bitgate.util.debug.Debug.*;

/**
 * This is a context class that contains information about a started server: it contains the IP address it was bound to,
 * the port number it listens for connections on, a flag indicating whether or not it uses secure sockets, and the protocol
 * in which the server handles connections.  It is used to instantiate a new server, which takes a
 * <code>new ServiceContext</code> to initialize.  It is generally used in this manner:
 * <p/>
 * <pre>new Service(new ServiceContext(80, false, &quot;HTTP&quot;));</pre>
 * <p/>
 * The server that contains the attached <code>ServiceContext</code> object then operates according to the rules set by
 * the context.  However, this is only part of the equation.  Once the <code>protocol</code> is set for the server, the
 * <code>Service</code> class behaves by loading in the appropriate protocol handler for the specified <code>protocol</code>,
 * and handles connections based on rules set therein.
 * 
 * @author Kenji Hollis &lt;kenji@bitgatesoftware.com&gt;
 * @version $Id: //depot/bitgate/bsse/src/bitgate/util/service/ServiceContext.java#1 $
 */
public class ServiceContext
{
    private String boundIp, boundProtocol, keyInstance, keyFile, storePassword, keyPassword, sslContext, boundName, clusterName;
    private int boundPort;
    private boolean boundSecure;
    
    /**
     * Instantiates a new context with IP address, port, secure flag, and protocol.
     *
     * @param ip The IP address to use.
     * @param port The port number to use.
     * @param secure Whether or not the server uses SSL connections.
     * @param protocol The protocol to use.
     */
    public ServiceContext(String ip, int port, boolean secure, String protocol)
    {
        initialize(ip, port, secure, protocol);
    }

    /**
     * Instantiates a new context with IP address, port, and protocol.
     *
     * @param ip The IP address to use.
     * @param port The port number to use.
     * @param protocol The protocol to use.
     */
    public ServiceContext(String ip, int port, String protocol)
    {
        initialize(ip, port, false, protocol);
    }

    /**
     * Instantiates a new context with port, secure flag, and protocol.
     *
     * @param port The port number to use.
     * @param secure Whether or not the server uses SSL connections.
     * @param protocol The protocol to use.
     */
    public ServiceContext(int port, boolean secure, String protocol)
    {
        initialize(null, port, secure, protocol);
    }

    /**
     * Instantiates a new context with port and protocol.
     *
     * @param port The port number to use.
     * @param protocol The protocol to use.
     */
    public ServiceContext(int port, String protocol)
    {
        initialize(null, port, false, protocol);
    }

    private void initialize(String ip, int port, boolean secure, String protocol)
    {
        this.boundIp = ip;
        this.boundPort = port;
        this.boundSecure = secure;
        this.boundProtocol = protocol;
		this.boundName = null;
		this.clusterName = null;

        this.keyInstance = this.boundSecure ? "JKS" : null;
        this.keyFile = this.boundSecure ? "secureKeys/keystore" : null;
        this.storePassword = this.boundSecure ? "unset1" : null;
        this.keyPassword = this.boundSecure ? "unset1" : null;
        this.sslContext = this.boundSecure ? "TLS" : null;
        
        if (isDebugEnabled()) {
        	debug("Initialize: ip='" + ip + "' port='" + port + "' secure='" + secure + "' protocol='" + protocol + "'");
        }
    }

    /**
     * Sets the name of the cluster that will be set for this service.
     *
     * @param clusterName The name of the cluster.
     */
    public void setClusterName(String clusterName)
    {
		this.clusterName = clusterName;
		
		if (isDebugEnabled()) {
			debug("Cluster name set to '" + clusterName + "'");
		}
    }

    /**
     * Sets the SSL Key Instance type.
     *
     * @param keyInstance The SSL Key Instance type.
     */
    public void setKeyInstance(String keyInstance)
    {
        this.keyInstance = keyInstance;
        
        if (isDebugEnabled()) {
        	debug("Key instance set to '" + keyInstance + "'");
        }
    }

    /**
     * Sets the SSL Key File.
     *
     * @param keyFile The SSL Key File.
     */
    public void setKeyFile(String keyFile)
    {
        this.keyFile = keyFile;
        
        if (isDebugEnabled()) {
        	debug("Key filename set to '" + keyFile + "'");
        }
    }

    /**
     * Sets the SSL Store Password.
     *
     * @param sslPassword The SSL Password.
     */
    public void setStorePassword(String sslPassword)
    {
        this.storePassword = sslPassword;
        
        if (isDebugEnabled()) {
        	debug("Store password set to '" + sslPassword + "'");
        }
    }

    /**
     * Sets the SSL Key Password.
     *
     * @param keyPassword The SSL Key Password.
     */
    public void setKeyPassword(String keyPassword)
    {
        this.keyPassword = keyPassword;
        
        if (isDebugEnabled()) {
        	debug("Key password set to '" + keyPassword + "'");
        }
    }

    /**
     * Sets the SSL Context.
     *
     * @param sslContext The SSL Context.
     */
    public void setSslContext(String sslContext)
    {
        this.sslContext = sslContext;
        
        if (isDebugEnabled()) {
        	debug("SSL Context set to '" + sslContext + "'");
        }
    }

    /**
     * Sets the name of the object from the services description.
     *
     * @param serviceName The service name to set.
     */
    public void setName(String serviceName)
    {
    	this.boundName = serviceName;
    }

    /**
     * Returns the current assigned IP address.
     *
     * @return <code>String</code> containing the current IP address.
     */
    public String getIp()
    {
        return this.boundIp;
    }

    /**
     * Returns the current assigned port number.
     *
     * @return <code>int</code> containing the current port.
     */
    public int getPort()
    {
        return this.boundPort;
    }

    /**
     * Returns whether or not a secure flag was set.
     *
     * @return <code>boolean</code> containing the current secure flag.
     */
    public boolean isSecure()
    {
        return this.boundSecure;
    }

    /**
     * Returns the current assigned protocol.
     *
     * @return <code>String</code> containing the current protocol.
     */
    public String getProtocol()
    {
        return this.boundProtocol;
    }

    /**
     * Returns the SSL Key Instance.
     *
     * @return <code>String</code> containing the current key instance.
     */
    public String getKeyInstance()
    {
        return this.keyInstance;
    }

    /**
     * Returns the SSL Key Filename.
     *
     * @return <code>String</code> containing the current key filename.
     */
    public String getKeyFile()
    {
        return this.keyFile;
    }

    /**
     * Returns the SSL Store Password.
     *
     * @return <code>String</code> containing the store password.
     */
    public String getStorePassword()
    {
        return this.storePassword;
    }

    /**
     * Returns the SSL Key Password.
     *
     * @return <code>String</code> containing the key password.
     */
    public String getKeyPassword()
    {
        return this.keyPassword;
    }

    /**
     * Returns the SSL Context.
     *
     * @return <code>String</code> containing the SSL Context.
     */
    public String getSslContext()
    {
        return this.sslContext;
    }

    /**
     * Returns the currently bound name from the services configuration.
     *
     * @return <code>String</code> containing the name.
     */
    public String getName()
    {
    	return this.boundName;
    }

    /**
     * Returns the name of the cluster to be used.
     *
     * @return <code>String</code> containing the cluster name.
     */
    public String getClusterName()
    {
    	return this.clusterName;
    }
}
